" init vim plug {{{
if empty(glob("$HOME/.vim/autoload/plug.vim"))
  silent !curl -fLo $HOME/.vim/autoload/plug.vim --create-dirs              
        \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
  autocmd!
  autocmd VimEnter * PlugInstall
endif
" }}}

" nvim/vim use same plug dir
set runtimepath+=~/.vim

let $MYVIMRC="$shell_dir/init.vim"

" plug list {{{
call plug#begin("$HOME/.vim/plugged")
  " color
  Plug 'joshdick/onedark.vim'
  " lsp client
  Plug 'neoclide/coc.nvim', {'branch': 'release'}
  " comment for multi languages
  Plug 'scrooloose/nerdcommenter'
  " pairs operators
  Plug 'jiangmiao/auto-pairs'
  Plug 'tpope/vim-surround'
  " expand visual selection
  Plug 'terryma/vim-expand-region'
  " tmux
  Plug 'christoomey/vim-tmux-navigator'
  " format
  Plug 'junegunn/vim-easy-align'
  " go
  Plug 'fatih/vim-go', { 'do': ':GoInstallBinaries' }
  " dir tree
  Plug 'scrooloose/nerdtree'
  Plug 'tpope/vim-vinegar'
  " keep input method per buffer in insert mode
  " Plug 'lilydjwg/fcitx.vim'
  " visible marks
  " Plug 'kshenoy/vim-signature'
  " static analyse
  Plug 'neomake/neomake'
  " async
  Plug 'tpope/vim-dispatch'
  " php
  " Plug 'marlonfan/coc-phpls'
  Plug 'adoy/vim-php-refactoring-toolbox'
  Plug 'phpactor/phpactor', { 'do': ':GoInstallBinaries' }
  " sudo read write
  Plug 'lambdalisue/suda.vim'
  " snippets
  Plug 'honza/vim-snippets'
  "Plug 'SirVer/ultisnips'
  Plug 'tpope/vim-repeat'
  " ][ pair operations
  Plug 'tpope/vim-unimpaired'
  " auto insert comma or semi-colon at eol
  Plug 'lfilho/cosco.vim'
  " swap func args
  Plug 'machakann/vim-swap'
  " extend motions
  Plug 'wellle/targets.vim'
  Plug 'easymotion/vim-easymotion'
  " git
  Plug 'tpope/vim-fugitive'
  Plug 'junegunn/gv.vim'
  Plug 'airblade/vim-gitgutter'
  Plug 'rhysd/git-messenger.vim'
  " quick split join
  Plug 'AndrewRadev/splitjoin.vim'
  " finder
  Plug 'junegunn/fzf', {'dir': '~/.fzf'}
  Plug 'junegunn/fzf.vim'
  " status
  Plug 'vim-airline/vim-airline'
  " substitute
  Plug 'tpope/vim-abolish'
  Plug 'Olical/vim-enmasse'
  " resize/move windows
  Plug 'simeji/winresizer'
  " close buffer keeping window layout
  Plug 'moll/vim-bbye'
  " multi cursors
"   Plug 'mg979/vim-visual-multi'
  Plug 'terryma/vim-multiple-cursors'
  " increment number by column
  Plug 'triglav/vim-visual-increment'
  " ctags
  Plug 'ludovicchabant/vim-gutentags'
  Plug 'majutsushi/tagbar'
  " extend %, even `if` `elseif`
  Plug 'andymass/vim-matchup'
  " search by selection
  Plug 'bronson/vim-visual-star-search'
  " collection of language packs
  Plug 'sheerun/vim-polyglot'
  " dbgp debug
  Plug 'vim-vdebug/vdebug'
  " markdown preview
  Plug 'iamcco/markdown-preview.nvim', { 'do': 'cd app & yarn install'  }
  " todo spell check plugin
  if has('nvim') || has('patch-8.0.902')
    Plug 'mhinz/vim-signify'
  else
    Plug 'mhinz/vim-signify', { 'branch': 'legacy' }
  endif
call plug#end()
" }}}

" common config {{{1
syntax on

"color config{{{2
color default
" highlight CursorLine term=bold cterm=bold guibg=Grey40
" highlight CursorColumn term=bold cterm=bold guibg=Grey40
"}}}

let g:maplocalleader = ','
let g:mapleader = ","

" set config {{{2
set updatetime=100
set undofile
set undodir=$HOME/.vim/undodir
set showcmd
set nu rnu
set nowrap
set clipboard+=unnamedplus
" cfdo argdo windo will prompt if not set
set hidden
" Some servers have issues with backup files, see #649.
set nobackup
set nowritebackup
" no swap file! This is just annoying
set noswapfile
" search
set ignorecase
set smartcase
set timeoutlen=500
" when at 3 spaces, and I hit > ... indent of 4 spaces in total, not 7
set shiftround
" always show signcolumns
set signcolumn=yes
" write automatically when quitting buffer
set autowrite
set viewoptions+=options
" }}}

" mappings {{{
vmap u y
" quick indent
vmap > >gv
vmap < <gv
" Disable anoying ex mode
nnoremap Q <Nop>
" source and PlugInstall
nnoremap <silent><leader>pi :source $MYVIMRC<CR> :PlugInstall<CR>
" Keep the cursor in place while joining lines
nnoremap J mzJ`z
" tabs operations
nnoremap <s-tab> :tabprev<CR>
nnoremap <tab> :tabnext<CR>
nnoremap tn :tabnew 
nnoremap tl :tablast<CR>
nnoremap tk :tabnext<CR>
nnoremap tj :tabprev<CR>
nnoremap th :tabfirst<CR>
nnoremap tL :tabm<CR>
nnoremap tF :tabm 0<CR>
nnoremap tc :tabclose<CR>
" terminal clipboard
noremap <leader>y "*y
noremap <leader>p "*p
" system cursorline
noremap <leader>Y "+y
noremap <leader>P "+p
" sort lines in range
vnoremap <leader>st :sort!<CR>
" delete blank lines in range
vnoremap <leader>rd :g/^$/d<CR>
vnoremap <leader>rl :s/\v\s+$//<CR>
nnoremap <leader>rl :s/\v\s+$//<CR>
" repeatable replace
vnoremap <leader>? y?<C-R>=escape(@", '\/~[]$.')<CR><CR>NcgN
vnoremap <leader>/ y/<C-R>=escape(@", '\/~[]$.')<CR><CR>Ncgn
" save file
inoremap <silent> <c-s> <esc>ms:w<CR>`s<right>
nnoremap <silent> <c-s> ms:w<CR>`s
" compress multi spaces in range
vnoremap <leader>ss :s#(\S) \+#\1 #g<CR>:noh<CR>
" quick split
nnoremap <leader>w <c-w>
nnoremap <leader>wm <c-w>_<c-w>\|
" MYVIMRC
nnoremap <leader>sv :source $MYVIMRC<CR><Left>
nnoremap <leader>dv :vsplit $MYVIMRC<CR>
" expand tab to spaces
nnoremap <leader>re :%retab
" toggle set
nnoremap <leader>sp :set paste!<CR>
nnoremap <leader>sl :set list!<CR>
nnoremap <leader>lw :set wrap!<CR>
nnoremap <leader>nu :let [&nu, &rnu] = [&nu, &nu+&rnu==1]<CR>
" remove ^M line endings
nnoremap <leader>rmm :%s/\r$\n/\r/<CR>
" manual set indent
nnoremap <leader>d4  :setlocal shiftwidth=4 tabstop=4 softtabstop=4<CR>
nnoremap <leader>d2  :sEtlocal shiftwidth=2 tabstop=2 softtabstop=2<CR>
inoremap <C-d> <Del>
" arrow keys will break dot repeat command if used in insert mode
imap <up> <nop>
imap <right> <nop>
imap <left> <nop>
imap <down> <nop>
" quick expand current file's directory in ex command
cnoremap <expr> %% getcmdtype() == ':' ? expand('%:h') : '%%'
" un-highlight when esc is pressed
nnoremap <silent><esc> :<C-u>noh<cr>
" tags
nnoremap <leader>tt :Tags<CR>
nnoremap <leader>tc :<C-U><C-R>=printf("Tags %s", expand("<cword>"))<CR><CR>
nnoremap <leader>tb :BTags<CR>
" quickfix edit replace
nnoremap <leader>EM :EnMasse<CR>
" quick manual fold
vnoremap <space> zf
nnoremap <space> za
nnoremap z<space> $zf%
" make/load view
nnoremap <leader>mv :mkview<CR>
nnoremap <leader>lv :loadview<CR>
" quick add current file and commit it
nnoremap <leader>gac :Git add % \| Git commit<CR>
nnoremap <leader>ga :Git add %<CR>
nnoremap <leader>go :Git checkout %<CR>
" reload file
nnoremap <leader>ll ms:e!<CR>`s
nnoremap <expr> gV '`[' . getregtype()[0] . '`]'
" Function to permanently delete views created by 'mkview'
function! MyDeleteView()
    let path = fnamemodify(bufname('%'),':p')
    " vim's odd =~ escaping for /
    let path = substitute(path, '=', '==', 'g')
    if empty($HOME)
    else
        let path = substitute(path, '^'.$HOME, '\~', '')
    endif
    let path = substitute(path, '/', '=+', 'g') . '='
    " view directory
    let path = &viewdir.'/'.path
    call delete(path)
    echo "Deleted: ".path
endfunction
command! Delview call MyDeleteView()
nnoremap <leader>Dv :call MyDeleteView() \| e<CR>
" find histories with the typed prefix
cmap <C-P> <UP>
cmap <C-N> <DOWN>
" map for breakpoints in file
nnoremap <leader>ba :let @+=printf('breakadd file %d %s', line('.'), expand('%:p'))<CR>
nnoremap <leader>bd :let @+=printf('breakdel file %d %s', line('.'), expand('%:p'))<CR>

" }}}

" }}}

" common autocmd {{{
augroup CursorLine
    au!
    au VimEnter * setlocal cursorline cursorcolumn
    au WinEnter * setlocal cursorline cursorcolumn
    au BufWinEnter * setlocal cursorline cursorcolumn
    au WinLeave * setlocal nocursorline nocursorcolumn
augroup END
augroup vimrc
  autocmd!
"  set filetype
  autocmd BufNewFile,BufRead .php_cs setlocal filetype=php
  autocmd BufWritePost $MYVIMRC source $MYVIMRC
  autocmd FileType vim set iskeyword+=:
  autocmd FileType * if &filetype != 'php'
    \ | setlocal formatoptions-=c formatoptions-=r formatoptions-=o
    \ | endif
  autocmd BufReadPost *.* silent! loadview
  autocmd BufWritePre *.* mkview!
"    delete empty buffer
  autocmd FileType help nnoremap <buffer> <tab> /\|\zs\S\{-}\|/<cr>
  autocmd FileType * set fdm=manual
  autocmd FileType vim set fdm=marker
augroup END
augroup numbertoggle
  autocmd!
  autocmd BufEnter,FocusGained,InsertLeave * set relativenumber
  autocmd BufLeave,FocusLost,InsertEnter   * set norelativenumber
augroup END
augroup FiletypeIndent
  au!
  autocmd FileType lua,html,php,javascript,python,htmldjango,c,sshconfig,go
    \ setlocal expandtab shiftwidth=4 tabstop=4 softtabstop=4 autoindent
  autocmd FileType conf,sh,zsh,yaml,markdown,json,snippets,vim
    \ setlocal shiftwidth=2 tabstop=2 softtabstop=2 expandtab autoindent
  autocmd FileType make
    \ set noexpandtab shiftwidth=4 tabstop=4 softtabstop=0
augroup END
" }}}

" common functions {{{
" repeat macro in visual range
xnoremap @ :<C-u>call ExecuteMacroOverVisualRange()<CR>
function! ExecuteMacroOverVisualRange()
  echo "@".getcmdline()
  execute ":'<,'>normal @".nr2char(getchar())
endfunction
" }}}

" nerdcommenter config {{{
let g:NERDSpaceDelims = 1
let g:NERDDefaultAlign='left'
" }}}

" nerdtree config {{{
nnoremap <silent> <leader>n :NERDTreeToggle<CR>
nnoremap <leader>tf :NERDTreeFind<CR>
" }}}

" auto-pairs config {{{
" todo M-? serial mappings
let g:AutoPairsFlyMode = 1
" }}}

" vim-easy-align config {{{
" Start interactive EasyAlign in visual mode (e.g. vipga)
xmap ga <Plug>(EasyAlign)
" Start interactive EasyAlign for a motion/text object (e.g. gaip)
nmap ga <Plug>(EasyAlign)
" }}}

" gutentags config {{{
let g:gutentags_ctags_exclude=['node_modules', 'vendor']
" }}}

" easymotion config {{{
" <leader>f{char} to move to {char}
map  <leader>ef <Plug>(easymotion-bd-f)
nmap <leader>ef <Plug>(easymotion-overwin-f)
" s{char}{char} to move to {char}{char}
nmap s <Plug>(easymotion-overwin-f2)
" Move to line
map <leader>L <Plug>(easymotion-bd-jk)
nmap <leader>L <Plug>(easymotion-overwin-line)
" Move to word
map  <leader>ew <Plug>(easymotion-bd-w)
nmap <leader>ew <Plug>(easymotion-overwin-w)
" }}}

" fugitive config {{{
nnoremap  <leader>gs :Gstatus<CR>
nnoremap  <leader>gb :Gblame<CR>
" }}}

" coc config {{{
set shortmess+=c
let g:coc_global_extensions = [
    \ 'coc-snippets',
    \ 'coc-json',
    \ 'coc-yaml',
    \ 'coc-html',
    \]
" Use <C-l> for trigger snippet expand.
imap <C-l> <Plug>(coc-snippets-expand)
" Use <C-j> for select text for visual placeholder of snippet.
vmap <C-j> <Plug>(coc-snippets-select)
" Use <C-j> for jump to next placeholder, it's default of coc.nvim
let g:coc_snippet_next = '<c-j>'
" Use <C-k> for jump to previous placeholder, it's default of coc.nvim
let g:coc_snippet_prev = '<c-k>'
" Use <C-j> for both expand and jump (make expand higher priority.)
" imap <C-j> <Plug>(coc-snippets-expand-jump)
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction
nmap <leader>rn <Plug>(coc-rename)
" GoTo code navigation.
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
" find symbol of current document
" Formatting selected code.
xmap <leader>fm  <Plug>(coc-format-selected)
" nmap <leader>fm  <Plug>(coc-format-selected)
" Use K to show documentation in preview window.
nnoremap <silent> K :call <SID>show_documentation()<CR>
function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  else
    call CocAction('doHover')
  endif
endfunction
" Apply AutoFix to problem on the current line.
nmap <leader>qf  <Plug>(coc-fix-current)
" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)
" coc command
nnoremap <leader>cm :CocCommand<CR>
nnoremap <leader>cl :CocList<CR>
nnoremap <leader>ct :CocList outline<CR>
" }}}

" fzf.vim config {{{
" todo fzf registers
imap <c-x><c-l> <plug>(fzf-complete-line)
imap <c-x><c-k> <plug>(fzf-complete-word)
imap <c-x><c-f> <plug>(fzf-complete-path)
" [Buffers] Jump to the existing window if possible
" find files in all
nnoremap <leader>ff :Files<CR>
" find files in git
nnoremap <leader>F :call fzf#run(fzf#wrap({'source': 'git ls-files --exclude-standard --others --cached'}))<CR>
" find cword
vnoremap <leader>rg  y:Rg <C-R>=escape(@", '\/~[]$.')<CR><CR>
nnoremap <silent><leader>rg :Rg <C-R><C-W><CR>
" find all snippetes
nnoremap <leader>fs  :CocList snippets<CR>
" find all mappings
nnoremap <leader>fp :<c-u>call fzf#vim#maps('', 0)<CR>
" find lines in loaded buffers
nnoremap <leader>fll :Lines<CR>
" find lines in current buffer
nnoremap <leader>fl :BLines<CR>
" find commands
nnoremap <leader>fc :Commands<CR>
" find historys
nnoremap <leader>fh :History<CR>
nnoremap <leader>: :History:<CR>
nnoremap <leader>/ :History/<CR>
" find buffers
let g:fzf_buffers_jump = 1
nnoremap <leader>fb :Buffers<CR>
let g:fzf_action = {
  \ 'ctrl-t': 'tab split',
  \ 'ctrl-h': 'split',
  \ 'ctrl-v': 'vsplit'
  \ }
nnoremap <leader>a :Rgi!<space>
nnoremap <leader>A :exec "Rgi! ".expand("<cword>")<cr>
"" --column: Show column number
" --line-number: Show line number
" --no-heading: Do not show file headings in results
" --fixed-strings: Search term as a literal string
" --ignore-case: Case insensitive search
" --no-ignore: Do not respect .gitignore, etc...
" --hidden: Search hidden files and folders
" --follow: Follow symlinks
" --glob: Additional conditions for search (in this case ignore everything in the .git/ folder)
augroup fzf
  autocmd!
augroup END
" ripgrep command to search in multiple files
autocmd fzf VimEnter * command! -bang -nargs=* Rg
  \ call fzf#vim#grep(
  \   'rg --column --line-number --no-heading --fixed-strings --ignore-case --no-ignore --hidden --follow --glob "!.git/*" --color "always" '.shellescape(<q-args>), 1,
  \   <bang>0 ? fzf#vim#with_preview('up:60%')
  \           : fzf#vim#with_preview('right:50%:hidden', '?'),
  \   <bang>0)
" ripgrep - ignore the files defined in ignore files (.gitignore...)
autocmd fzf VimEnter * command! -bang -nargs=* Rgi
  \ call fzf#vim#grep(
  \   'rg --column --line-number --no-heading --fixed-strings --ignore-case --hidden --follow --glob "!.git/*" --color "always" '.shellescape(<q-args>), 1,
  \   <bang>0 ? fzf#vim#with_preview('up:60%')
  \           : fzf#vim#with_preview('right:50%:hidden', '?'),
  \   <bang>0)
" ripgrep - ignore the files defined in ignore files (.gitignore...) and doesn't ignore case
autocmd fzf VimEnter * command! -bang -nargs=* Rgic
  \ call fzf#vim#grep(
  \   'rg --column --line-number --no-heading --fixed-strings --hidden --follow --glob "!.git/*" --color "always" '.shellescape(<q-args>), 1,
  \   <bang>0 ? fzf#vim#with_preview('up:60%')
  \           : fzf#vim#with_preview('right:50%:hidden', '?'),
  \   <bang>0)
" ripgrep - ignore the files defined in ignore files (.gitignore...) and doesn't ignore case
autocmd fzf VimEnter * command! -bang -nargs=* Rgir
  \ call fzf#vim#grep(
  \   'rg --column --line-number --no-heading --hidden --follow --glob "!.git/*" --color "always" '.shellescape(<q-args>), 1,
  \   <bang>0 ? fzf#vim#with_preview('up:60%')
  \           : fzf#vim#with_preview('right:50%:hidden', '?'),
  \   <bang>0)
" ripgrep - ignore the files defined in ignore files (.gitignore...) and doesn't ignore case and activate regex search
autocmd fzf VimEnter * command! -bang -nargs=* Rgr
  \ call fzf#vim#grep(
  \   'rg --column --line-number --no-heading --hidden --no-ignore --follow --glob "!.git/*" --color "always" '.shellescape(<q-args>), 1,
  \   <bang>0 ? fzf#vim#with_preview('up:60%')
  \           : fzf#vim#with_preview('right:50%:hidden', '?'),
  \   <bang>0)
nnoremap <leader>df :diffthis \| :vnew \| r # \| exe "norm! ggdd" \| :diffthis<CR>
" }}}

" gitgutter config {{{
" toggle git unchanged lines
nnoremap <leader>hf  :GitGutterFold<CR>
" }}}

" suda.vim config {{{
cnoremap w!! execute ':w suda://%' " Save files as root
" }}}

" bbye config {{{
" delete buffer but keep window layout
nnoremap <leader>q :Bdelete<CR>
" }}}

" tarbar config {{{
nnoremap <leader>tt :TagbarToggle<CR>
" }}}

" airline config {{{
let g:airline_section_z="%3p%%:%-2c\ %l/%-4L[%{winnr()}"
" }}}

" winresizer config {{{
let g:winresizer_start_key = '<C-T>'
" }}}

" cosco config {{{
augroup numbertoggle
  autocmd!
  autocmd FileType javascript,css,php,lua nmap <silent> <leader>; <Plug>(cosco-commaOrSemiColon)
  autocmd FileType javascript,css,php,lua imap <silent> <leader>; <c-o><Plug>(cosco-commaOrSemiColon)
augroup END
" }}}

" neomake config {{{
let g:neomake_logfile='/tmp/neomake.log'
let g:neomake_verbose = -1
let g:neomake_open_list = 2
augroup my_neomake
  au!
  autocmd User NeomakeJobFinished checktime
augroup END
nnoremap <leader>mk :Neomake<CR>
" call neomake#configure#automake('w')
let g:neomake_php_enabled_makers = ['phpstan', 'php', 'phpcs']
let g:neomake_php_phpcs_maker = {
            \ 'exe': 'php-cs-fixer',
            \ 'args': ['fix'],
            \ 'errorformat':
            \ '%-GFile\,Line\,Column\,Type\,Message\,Source\,Severity%.%#,'.
            \ '"%f"\,%l\,%c\,%t%*[a-zA-Z]\,"%m"\,%*[a-zA-Z0-9_.-]\,%*[0-9]%.%#',
            \ }
" find .php_cs file for the project
let php_cs_config_file_path = neomake#utils#FindGlobFile('.php_cs')
if !empty(php_cs_config_file_path)
  call extend(g:neomake_php_phpcs_maker.args, ['--config', php_cs_config_file_path])
endif
let g:neomake_php_phpstan_maker = {
            \ 'args': ['analyse',  '--autoload-file', '_ide_helper.php', '--error-format', 'raw', '--no-progress', '--level', '0'],
            \ 'errorformat': '%W%f:%l:%m',
            \ }
" }}}

"phpactor/phpactor config {{{
" todo phpactor as lsp
augroup PhpactorMappings
  au!
  au FileType php nmap <buffer> <leader>u :PhpactorImportClass<CR>
  au FileType php nmap <buffer> <leader>e :PhpactorClassExpand<CR>
  au FileType php nmap <buffer> <leader>ua :PhpactorImportMissingClasses<CR>
  au FileType php nmap <buffer> <leader>mm :PhpactorContextMenu<CR>
  au FileType php nmap <buffer> <leader>nn :PhpactorNavigate<CR>
  au FileType php,cucumber nmap <buffer> <leader>o
      \ :PhpactorGotoDefinition<CR>
  au FileType php,cucumber nmap <buffer> <leader>Oh
      \ :PhpactorGotoDefinitionHsplit<CR>
  au FileType php,cucumber nmap <buffer> <leader>Ov
      \ :PhpactorGotoDefinitionVsplit<CR>
  au FileType php,cucumber nmap <buffer> <leader>Ot
      \ :PhpactorGotoDefinitionTab<CR>
  " au FileType php nmap <buffer> <leader>K :PhpactorHover<CR>
  " au FileType php nmap <buffer> <leader>tt :PhpactorTransform<CR>
  " au FileType php nmap <buffer> <leader>cc :PhpactorClassNew<CR>
  " au FileType php nmap <buffer> <leader>ci :PhpactorClassInflect<CR>
  " au FileType php nmap <buffer> <leader>fr :PhpactorFindReferences<CR>
  " au FileType php nmap <buffer> <leader>mf :PhpactorMoveFile<CR>
  " au FileType php nmap <buffer> <leader>cf :PhpactorCopyFile<CR>
  " au FileType php nmap <buffer> <leader>fi :PhpactorGotoImplementations<CR>
  au FileType php nmap <buffer> <silent> <leader>ee
      \ :PhpactorExtractExpression<CR>
  au FileType php vmap <buffer> <silent> <leader>ee
      \ :<C-u>PhpactorExtractExpression<CR>
  au FileType php vmap <buffer> <silent> <leader>em
      \ :<C-u>PhpactorExtractMethod<CR>
augroup END
"}}}
